/**
 * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
 */
package cn.eonshine.base.core.util;

import java.util.Date;
import java.util.Locale;

import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.UnavailableSecurityManagerException;
import org.apache.shiro.session.InvalidSessionException;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;

import cn.eonshine.base.core.shiro.ShiroUser;
import cn.eonshine.cuba.inf.common.util.DateUtils;
import cn.eonshine.cuba.inf.modular.sys.entity.User;
import cn.eonshine.cuba.inf.modular.sys.mapper.UserMapper;

/**
 * the user tool class User Tools 
 * @author jeeplus
 * @version 2013-12-05
 */
public class UserUtils {

	private static UserMapper userDao = SpringContextHolder.getBean(UserMapper.class);
//	private static RoleMapper roleDao = SpringContextHolder.getBean(RoleMapper.class);
//	private static MenuMapper menuDao = SpringContextHolder.getBean(MenuMapper.class);

	public static final String USER_CACHE = "userCache";
	public static final String USER_CACHE_ID_ = "id_";
	public static final String USER_CACHE_LOGIN_NAME_ = "ln";
	public static final String USER_CACHE_LIST_BY_OFFICE_ID_ = "oid_";
	public static final String USER_CACHE_LOCAL_ID_ = "local_id_";

	public static final String CACHE_ROLE_LIST = "roleList";
	public static final String CACHE_MENU_LIST = "menuList";
	public static final String CACHE_AREA_LIST = "areaList";
	public static final String CACHE_OFFICE_LIST = "officeList";
	public static final String CACHE_OFFICE_ALL_LIST = "officeAllList";


	/**
 * get the user Get users based on ID based on ID 
	 * @param id
	 * @return No return to null Cannot get null return 
	 */
	public static User get(String id){
		User user = (User)CacheUtils.get(USER_CACHE, USER_CACHE_ID_ + id);
		if (user ==  null){
			user = userDao.selectById(id);
			if (user == null){
				return null;
			}
//			user.setRoleList(roleDao.findList(new Role(user)));
			CacheUtils.put(USER_CACHE, USER_CACHE_ID_ + user.getId(), user);
			CacheUtils.put(USER_CACHE, USER_CACHE_LOGIN_NAME_ + user.getAccount(), user);
		}
		return user;
	}

	

	/**
 * get the user Get users based on login name based on the login name 
	 * @param loginName
	 * @return No return to null Cannot get null return 
	 */
	public static User getByLoginName(String loginName){
		User user = (User)CacheUtils.get(USER_CACHE, USER_CACHE_LOGIN_NAME_ + loginName);
		if (user == null){
			user = userDao.getByAccount(loginName);
			if (user == null){
				return null;
			}
//			user.setRoleList(roleDao.findList(new Role(user)));
			CacheUtils.put(USER_CACHE, USER_CACHE_ID_ + user.getId(), user);
			CacheUtils.put(USER_CACHE, USER_CACHE_LOGIN_NAME_ + user.getAccount(), user);
		}
		return user;
	}

	/**
 * clear the current user cache Clear current user cache 
	 */
	public static void clearCache(){
		removeCache(CACHE_ROLE_LIST);
		removeCache(CACHE_MENU_LIST);
		removeCache(CACHE_AREA_LIST);
		removeCache(CACHE_OFFICE_LIST);
		removeCache(CACHE_OFFICE_ALL_LIST);
		UserUtils.clearCache(getUser());
	}

	/**
 * clear the specified user cache Clear the specified user cache 
	 * @param user
	 */
	public static void clearCache(User user){
		CacheUtils.remove(USER_CACHE, USER_CACHE_ID_ + user.getId());
		CacheUtils.remove(USER_CACHE, USER_CACHE_LOGIN_NAME_ + user.getAccount());
		CacheUtils.remove(USER_CACHE, USER_CACHE_LOCAL_ID_+ user.getId());
	}

	/**
 * get the current user Get current user 
	 * @return 取不到返回 new User()    Can't get back new User()
	 */
	public static User getUser(){
		ShiroUser principal = getPrincipal();
		if (principal!=null){
			User user = get(principal.getId()+"");
			if (user != null){
				return user;
			}
			return new User();
		}
		// If there is no login, the User object that is instantiated is returned. If it is not logged in, an empty User object is instantiated. 
		return new User();
	}

	/**
 * get international voice Get international voice 
	 * @return
	 */
	public static Locale getUserLocal(){
		User user = getUser();
		if(user == null) {
			return Locale.US;
		}
		Locale local = (Locale)CacheUtils.get(USER_CACHE, USER_CACHE_LOCAL_ID_+ user.getId());
		if(local == null) {
			local = Locale.US;
		}
		return local;
	}

	public static void setUserLocal(String lang) {
		User user = getUser();
		if(user != null && StringUtils.isNotBlank(user.getId()+"") && StringUtils.isNotBlank(lang)) {
			Locale local = (Locale)CacheUtils.get(USER_CACHE, USER_CACHE_LOCAL_ID_+ user.getId());
			if(lang.equalsIgnoreCase("zh_CN")) {
				local = Locale.SIMPLIFIED_CHINESE;
			} else {
				local = Locale.US;
			}
			CacheUtils.put(USER_CACHE, USER_CACHE_LOCAL_ID_+ user.getId(), local);
		}
	}


	/**
 * get the main object of authorization Get Authorized Main Object 
	 */
	public static Subject getSubject(){
		return SecurityUtils.getSubject();
	}

	/**
 * get the current logged in object Get current registrant object 
	 */
	public static ShiroUser getPrincipal(){
		try{
			Subject subject = SecurityUtils.getSubject();
			ShiroUser principal = (ShiroUser)subject.getPrincipal();
			if (principal != null){
				return principal;
			}
//			subject.logout();
		}catch (UnavailableSecurityManagerException e) {

		}catch (InvalidSessionException e){

		}
		return null;
	}

	public static Session getSession(){
		try{
			Subject subject = SecurityUtils.getSubject();
			Session session = subject.getSession(false);
			if (session == null){
				session = subject.getSession();
			}
			if (session != null){
				return session;
			}
//			subject.logout();
		}catch (InvalidSessionException e){

		}
		return null;
	}

	// ============== User Cache ==============

	public static Object getCache(String key) {
		return getCache(key, null);
	}

	public static Object getCache(String key, Object defaultValue) {
//		Object obj = getCacheMap().get(key);
		Object obj = getSession().getAttribute(key);
		return obj==null?defaultValue:obj;
	}

	public static void putCache(String key, Object value) {
//		getCacheMap().put(key, value);
		getSession().setAttribute(key, value);
	}

	public static void removeCache(String key) {
//		getCacheMap().remove(key);
		getSession().removeAttribute(key);
	}

	public static String getTime(Date date){
		StringBuffer time = new StringBuffer();
        Date date2 = DateUtils.getCubaDate(new Date());
        long temp = date2.getTime() - date.getTime();    
        long days = temp / 1000 / 3600/24;                // Difference hours Difference hours 
        if(days>0){
        	time.append(days+ "Heaven"); 
        }
        long temp1 = temp % (1000 * 3600*24);
        long hours = temp1 / 1000 / 3600;                // Difference hours Difference hours 
        if(days>0 || hours>0){
        	time.append(hours+ "Hour"); 
        }
        long temp2 = temp1 % (1000 * 3600);
        long mins = temp2 / 1000 / 60;                    // Difference in minutes with a difference of minutes 
        time.append(mins + "Minutes"); 
        return  time.toString();
	}

}